feat: Bash 優先指示を解除する native-file-tools フックを追加(v0.78.0) - #170
Merged
Conversation
Claude Code 2.1.261 が auto / bypassPermissions セッションに注入する Bash 優先指示(未文書化 flag CLAUDE_CODE_THRIFTY_SONIC)で、Edit|Write フック・paths 付き Rules・nested CLAUDE.md・native rewind が無音で 動かなくなる問題を実 CLI で再現し、env-only feature として CLAUDE_CODE_THRIFTY_SONIC=0 を配布する(Standard / Full 既定有効)。 - features/native-file-tools を追加し、registry / profiles / wizard / i18n / MDM 許可キー / docs / CHANGELOG 0.78.0 に登録 - 後発キーの補完を _fill_late_feature_defaults に集約し、custom プロファイルの保存設定再利用で agent-teams の env が配布されない 既存バグも修正 - 回帰テスト tests/unit/test-native-file-tools.sh(修正前 12 件 FAIL)と 実 CLI 検証ハーネス tests/manual/bash-first-steer/(CI 非連動)を追加 - README(日英)に security-guidance 編集時警告の適用条件と native rewind が Bash 編集を追跡しない注記を追加
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
レビューで確認した 3 件に対応した。 - tests/unit/test-native-file-tools.sh: `if ( set -e; ... )` の条件内では set -e が効かず、最後のコマンドの終了コードしか判定に使われない。 レジストリ・hook トークン・--hooks CSV の各アサーションに `|| exit 1` を 付けて拘束化した。main(修正前)に対する失敗件数は 14 件から 15 件になる - tests/manual/bash-first-steer/run-case.sh: BFS_KIT_SETTINGS に渡した kit 生成 settings.json が SessionStart / SessionEnd フックを含む場合は 拒否する。フックコマンドは実環境の ~/.claude/hooks/ を指すため、 Standard / Full の既定値では auto-update(git pull + setup.sh --update) などが fixture セッションから実インストールに対して走ってしまう - ハーネスの README と CHANGELOG の記述を実測に合わせて修正 (修正前の失敗件数 12 件 → 17 件中 15 件、リリース日 2026-09-07) Claude-Session: https://claude.ai/code/session_01C9mrbbXQgV9fJ8Zy5UoEYc
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
This was referenced Sep 8, 2026
okash1n
added a commit
that referenced
this pull request
Sep 8, 2026
Bash は if の条件として実行される ( ... ) サブシェルとその内部の set -e に 対して errexit を無視し、( ... ) || rc=$? も同じ扱いになる。最後のコマンド の終了コードしか判定に使われないため、途中の [[ ]] や関数呼び出しの失敗は 無視されていた(#170 で test-native-file-tools.sh の 3 ブロックを修正済み)。 tests/unit/*.sh の該当ブロックを全数監査し、実際に非拘束だった 12 文に house style の `|| exit 1` を付けた。 - test-deploy-refactor.sh (2): build_settings_file の終了コードが捨てられ、 MDM 側は最終判定が `! jq -e` なのでビルド失敗でも空振りで pass していた - test-ghostty.sh (5): 否定テストの fixture 生成(_ghostty_test_make_app、 ln -s)と deploy_ghostty_config の終了コード。fixture が作れなくても 「拒否された」扱いで pass していた - test-mdm-install.sh (5): launcher の quiescence / quick-exit ケースは 最後のコマンドが trap - EXIT や while で _rc が常に 0 になり、PGID と group 状態のアサーションが死んでいた 他の 5 ファイル(fonts / prerequisites / update-refactor / setup-refactor / mdm-detect)は既に拘束済みで変更なし。各修正はアサーションを反転させる mutation check で FAIL に転じることを確認した。MDM ファイルは CI の run-mdm-tests.sh が実行時検証。 Claude-Session: https://claude.ai/code/session_01C9mrbbXQgV9fJ8Zy5UoEYc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
Claude Code 2.1.261 は auto / bypassPermissions モードのセッションに「ファイルの読み書きは Read/Edit/Write ではなく cat / sed / heredoc で行え」という指示を注入する(バイナリ内の未文書化 feature flag
CLAUDE_CODE_THRIFTY_SONIC。Fable 5.1 系モデルでは強制有効、Opus 5 は GrowthBook のコホート配信)。この状態ではモデルが Read/Edit/Write をほぼ使わないため、キットの次の仕組みが無音で動かなくなる。PostToolUseEdit|Writeの prettier-hooks / biome-hooks、PreToolUseWriteの doc-blocker、PostToolUseWriteの doc-size-guardpaths:付き Rules とサブディレクトリの CLAUDE.md(Read 時に読み込まれる仕組みのため)settings.jsonのenvにCLAUDE_CODE_THRIFTY_SONIC="0"を入れる env-only featurenative-file-toolsを追加し、Standard / Full で既定有効にする。あわせて、レビューで見つかった既存バグ(custom プロファイルで保存設定を再利用すると agent-teams の env が配布されない)を修正した。発端: https://kawasin73.hatenablog.com/entry/2026/09/05/092056
実 CLI での再現と修正確認
条件: Claude Code 2.1.261、claude-fable-5-1、
--permission-mode auto、--setting-sources project --strict-mcp-config --permission-prompts none。合成 git リポジトリを新規セッションごとに複製し、同一課題(TS 関数リネーム、docs 追記、AGENTS.md 作成、SUMMARY.md 作成)を与えた。観測はstream-json --include-hook-events、観測専用フック(PreToolUse / PostToolUse / InstructionsLoaded)、git 差分、トランスクリプトに永続化されるauto_modeattachment で行い、モデルの自己申告は使っていない。bashFirst)"0"×3"1""0"・「Bash で編集しろ」※ 初回 3 セッションは課題文の AGENTS.md 作成が
seqで済む書き方で Write が発生せず、doc-size-guard の正常対照が成立していない。課題文を修正した以降はすべて発火した。default/planモードは実測していない(バイナリの条件式が auto / bypassPermissions 以外で即座に空を返すことからの判断)。prettier-hooks は PATH に prettier がなく、同じtool_input.file_path契約の biome-hooks で代表した。修正内容
features/native-file-tools/:hooks.jsonは{"env":{"CLAUDE_CODE_THRIFTY_SONIC":"0"}}のみ。agent-teams/no-flickerと同じ配布形態lib/features.sh、profiles/*.conf(Standard / Full true、Minimal false)、wizard/defaults.conf、wizard/registry.sh(_CONFIG_KEYS、HOOK_KEYS / HOOK_TOKENSnative-tools/ HOOK_LABELS)、wizard/steps.sh(確認画面・非対話デフォルト)、wizard/wizard.sh(グローバル初期化・更新経路の補完)、i18n/{en,ja}/strings.sh、mdm/install-mdm.sh(許可キー 2 か所)_fill_late_feature_defaults(wizard/registry.shに新設): agent-teams / native-file-tools の後発キー補完を集約し、更新経路(_restore_config_from_manifest)・非対話 fresh install(_fill_noninteractive_defaults)・対話ウィザードの保存設定再利用(fill_missing_profile_defaults)の 3 経路から呼ぶ--hooks例、security-guidance 編集時警告の適用条件、native rewind が Bash 編集を追跡しない注記。docs/wizard-config-mapping*.md、docs/mdm/README.md、commands/checkpoint.md、CLAUDE.md、CHANGELOG.md(0.78.0)tests/unit/test-native-file-tools.sh(17 件。修正前のコードでは 12 件が失敗)、tests/unit/test-docs-sync.shにキー追加tests/manual/bash-first-steer/。合成 fixture 生成・ケース実行・集計スクリプトと期待結果表。モデルを実際に呼ぶため通常 CI には組み込まない修正した既存バグ
custom プロファイルで
setup.shを直接再実行し「保存された設定を再利用する」を選ぶと、fill_missing_profile_defaultsはプロファイル conf を読むだけで、conf を持たない custom では後発キーが空のままになり、env フラグメントが出力されていなかった(agent-teams で #138 以来発生。install.sh経由は常に--updateが付くため影響せず、README が案内する「リポジトリ更新後に./setup.shを再実行」の手順でのみ発生)。fill_missing_profile_defaultsからも補完を呼ぶようにし、回帰テストを追加した。保証範囲と残る制約
settings.jsonから除去する([P4-14] 配布設定の世代依存ピンの整理(agent-teams env / effortLevel / legacy 経路 / dead var) #120 の effortLevel 撤去と同じ経路)。残っても未知の env は無視される更新経路(レビュー観点)
--profile=custom非対話)_fill_noninteractive_defaults→_fill_late_feature_defaultsで truesetup.sh --update/ 自動アップデート_restore_config_from_manifestが profile conf → 保存 conf → 補完の順で決める。保存 conf の明示的なfalseは保持setup.sh直接再実行 + 保存設定再利用(対話)fill_missing_profile_defaults→_fill_late_feature_defaults(今回修正)--hooksCSVnative-toolstest-mdm-keys-in-syncで profiles / registry / allowlist の一致を検査build_settings_fileを通る実行した確認
bash -c 'source tests/helpers.sh; source tests/unit/test-native-file-tools.sh; print_summary': 修正前 12/14 FAIL → 修正後 17/17 PASSbash tests/run-unit-tests.sh: 828 件中 827 PASS。唯一の FAIL はfonts: direct download fallback receives font definitionで、base コミット e3a0dd3 の clean worktree でも同一失敗(環境依存、今回の変更と無関係)。この FAIL でprint_summaryが非ゼロ終了し MDM スイートに到達しないため、MDM は単独実行したMDM_TEST_BASH=/bin/bash /bin/bash tests/run-mdm-tests.sh(前面・単独実行): 12 ファイル 987 assertions、FAIL 0。nohup 下では runner の HUP self-test が必ず失敗するので注意bash tests/run-scenarios.sh: 49 件中 48 PASS、SKIP 1(bash4-noninteractive-unavailable、Bash 4+ 環境の既定)git ls-files -z '*.sh' | xargs -0 -n 1 shellcheck -S warning(未追跡の新規 .sh も含めて 105 本): 指摘 0setup.sh --profile=full --hooks=doc-block,biome,doc-size,native-toolsが生成したsettings.jsonをそのまま使った auto モード 2 セッションで、指示注入なし・Read/Edit/Write 使用・3 フック発火・paths Rules / nested CLAUDE.md ロードを確認実 CLI の生ログ(stream-json、観測フックの JSONL、git 差分)はセッション固有の一時ディレクトリにあり、PR には含めていない。再実行手順は
tests/manual/bash-first-steer/README.md。判断を仰ぎたい点
falseのままにするか(Minimal は rules を配布するが、キット配布の rules はpaths:なしで起動時ロードのため影響は利用者追加分に限られる)